<template>
  <div>
    <div>
      <!--
        fixed 固定定位
        外部将fixed(true, false) 传入组件内部 props 中判断是否 触发有固定定位的类名
       -->
      <van-nav-bar fixed>
        <!-- v-slot 具名插槽 #简写 -->
        <template v-slot:left>
          <img class="bili" src="../../assets/logo.png" alt="" @click="fn" />
        </template>
        <template #right>
          <!-- 坑: postcss 只能翻译style里的css样式代码，标签行内样式px无法转换rem，所以需要手动转换 -->
          <van-icon
            name="search"
            size="0.48rem"
            color="#fff"
            @click="searchFn"
          />
        </template>
      </van-nav-bar>
    </div>
    <div class="tab">
      <!-- tab栏导航
          van-tabs  一行容器
          van-tab    每个tab栏
          animated   切换动画
      -->
      <van-tabs animated v-model="active" swipeable @change="switchChannel">
        <!-- 通过 name 传入频道id 自动将name的值（id） 同步到  v-model="active"-->
        <van-tab
          :title="obj.name"
          v-for="obj in userNavigationList"
          :key="obj.id"
          :name="obj.id"
        >
          <!-- 向子组件传入频道id -->
          <ArticleList :channelId="obj.id"></ArticleList>
        </van-tab>
      </van-tabs>
      <van-icon
        name="plus"
        size="0.37333334rem"
        class="moreChannels"
        @click="popupFn"
      />
      <!-- 首页弹出层 -->
      <van-popup v-model="show" get-container="body" class="channe">
        <ChannelEdit
          :userList="this.userNavigationList"
          :missionList="missionChannel"
          @addChannels="addChannel"
          @subUserChanne="subUserChanneFn"
          @closeMaskedEV="closeMaskedFn"
          ref="reEdit"
          v-model="active"
        ></ChannelEdit>
      </van-popup>
    </div>
  </div>
</template>

<script>
import { getUserChanneApi, getChannelApi, addChannelApi, removeUserChannelApi } from '@/api'
import ArticleList from './components/ArticleList.vue'
import ChannelEdit from './ChannelEdit.vue'

export default {
  // eslint-disable-next-line vue/multi-word-component-names
  name: 'Home',
  data () {
    return {
      active: 0, // tab 频道id 初始化频道id 为0
      userNavigationList: [], // 首页频道列表
      show: false, // 加号蒙版状态
      allNavigationList: [], // 所有频道列表
      pageScrollbarObj: {} // 存储每个频道的滚动条距离
    }
  },
  methods: {
    //  点击导航栏图片 跳转到登录页面
    fn () {
      this.$router.push({
        path: '/login'
      })
    },

    //  点击将当前频道id同步到 active 在传入 axios中获取当前页面数据
    async zapping () {
      // 获取首页 频道
      const res = await getUserChanneApi()
      // console.log(res)
      this.userNavigationList = res.data.data.channels
    },

    // 加号触发蒙版显示
    popupFn () {
      this.show = true
    },

    // 添加频道
    async addChannel (obj) {
      // 因为计算属性的原因 push到用户频道后 原来的更多频道不用跟新 计算属性自动同步
      this.userNavigationList.push(obj)

      // 先将推荐 过滤出去
      const fArr = this.userNavigationList.filter((obj) => obj.id !== 0)
      const mopArray = fArr.map((obj, index) => {
        const mapArr = { ...obj } // 浅拷贝  深拷贝拷贝的是地址  不能直接删 因为对象地址一样, 当前页面用户数组内容一块删了
        delete mapArr.name // 将不符合后台对象属性删除
        mapArr.seq = index // 赋予新属性
        return mapArr
      })
      await addChannelApi(mopArray)
    },

    // 删除用户已有频道(表面删除)
    async subUserChanneFn (userObj) {
      this.userNavigationList = this.userNavigationList.filter((obj) => obj.id !== userObj.id)
      await removeUserChannelApi(userObj.id)
    },

    // 点击完成向后台请求删除用户频道
    async removeChannelFn () {

    },

    // 点击关闭遮罩层
    closeMaskedFn () {
      this.show = false
      // 用 ref 绑定组件 $refs获取此组件的实例对象 直接控制此实例中 编辑状态的 变量
      this.$refs.reEdit.isOmit = false
    },

    // 跳转搜索页面
    searchFn () {
      this.$router.push('/search')
    },

    // 动态获取滚动条的距离
    screentFn () {
      // 导航切换获取
      this.$route.meta.screenT = document.documentElement.scrollTop || document.body.scrollTop
      // 频道切换获取 tab切换后设置滚动条位置
      this.pageScrollbarObj[this.active] = this.$route.meta.screenT
    },

    // 切换频道 -> 触发
    switchChannel () {
      // tab 切换时，这个组件内部，会把切走的容器height设置为0，滚动条没有高度会到顶部
      // 切回来了的一瞬间，没有高度，滚动事件从底下上来也被触发了，所以才把数据里设置为0
      // 切回来的一瞬间，高度为0，设置滚动位置也没用
      this.$nextTick(() => {
        document.documentElement.scrollTop = this.pageScrollbarObj[this.active]
        document.body.scrollTop = this.pageScrollbarObj[this.active] // 优化手机端
      })
    }

  },
  async created () {
    // 页面初始化后调用获取首页数据
    this.zapping()
    // 获取所有频道列表
    const res = await getChannelApi()
    this.allNavigationList = res.data.data.channels
  },
  components: {
    // eslint-disable-next-line vue/no-unused-components
    ArticleList,
    // eslint-disable-next-line vue/no-unused-components
    ChannelEdit
  },
  // 用所有频道过滤 已有频道  得到未添加的频道
  computed: {
    missionChannel () {
      return this.allNavigationList.filter((obj) => {
        const index = this.userNavigationList.findIndex((smallObj) => {
          return obj.id === smallObj.id // 不相等返回 -1
        })
        if (index > -1) {
          // 不相等返回false 过滤掉
          return false
        } else {
          return true // 相等添加到新数组中
        }
      })
    }
  },

  // activated deactivated  组件缓存可用 每当切换到当前页面都会执行activated 切到其他页面会执行deactivated
  activated () {
    // 没次切换到当前页面触发此函数注册 滚动事件 动态监测滚动距离并存储到路由中
    window.addEventListener('scroll', this.screentFn)
    // 立即将路由中存储的滚动条距离赋予给当前页面滚动条
    document.documentElement.scrollTop = this.$route.meta.screenT
    document.body.scrollTop = this.$route.meta.screenT
  },
  deactivated () {
    // 离开当前页面注销事件
    window.removeEventListener('scroll', this.screentFn)
  }
}
</script>

<style lang="less" scoped>
.bili {
  // 设置导航栏 左边图片大小
  width: 100px;
  height: 40px;
}
.tab {
  // 底部在 Layout/index.vue - 给二级路由挂载点容器上给了一个 padding-bottom
  padding-top: 46px;
}
// 设置 导航栏定位
/deep/ .van-tabs__wrap {
  position: fixed;
  top: 46px;
  z-index: 1;
} // 标签内容撑大下移， 默认导航栏定位后会脱离标准流 会压着下面的文章列表
.van-tabs {
  padding-top: 45px;
}

// 设置小图标的样式
.moreChannels {
  position: fixed;
  top: 62px;
  right: 0px;
  z-index: 999;
  padding: 0 10px;
  background-color: #fff;
}

// 加号蒙版大小  vh vw css3语法 参考的是浏览器百分比
.channe {
  width: 100vw;
  height: 100vh;
}
</style>
